package uk.co.douglashoskins.weathercompare.providers;

import java.io.IOException;

import javax.microedition.lcdui.Image;

import org.json.me.JSONArray;
import org.json.me.JSONException;
import org.json.me.JSONObject;

import uk.co.douglashoskins.weathercompare.Assets;
import uk.co.douglashoskins.weathercompare.WeatherCompare;
import uk.co.douglashoskins.weathercompare.controller.WeatherObj;
import uk.co.douglashoskins.weathercompare.services.NetQueueCallback;
import uk.co.douglashoskins.weathercompare.util.Weather;
/*
 * 0   tornado
1   tropical storm
2   hurricane
3   severe thunderstorms
4   thunderstorms
5   mixed rain and snow
6   mixed rain and sleet
7   mixed snow and sleet
8   freezing drizzle
9   drizzle
10  freezing rain
11  showers
12  showers
13  snow flurries
14  light snow showers
15  blowing snow
16  snow
17  hail
18  sleet
19  dust
20  foggy
21  haze
22  smoky
23  blustery
24  windy
25  cold
26  cloudy
27  mostly cloudy (night)
28  mostly cloudy (day)
29  partly cloudy (night)
30  partly cloudy (day)
31  clear (night)
32  sunny
33  fair (night)
34  fair (day)
35  mixed rain and hail
36  hot
37  isolated thunderstorms
38  scattered thunderstorms
39  scattered thunderstorms
40  scattered showers
41  heavy snow
42  scattered snow showers
43  heavy snow
44  partly cloudy
45  thundershowers
46  snow showers
47  isolated thundershowers
3200    not available
 */
public class Yahoo implements NetQueueCallback, WeatherProvider {
	private int state;
	private WeatherCallback wc;
	public void getWeather(double lat, double lng, WeatherCallback wc) {
		this.wc = wc;
		// first of all get WOEID from yahoo APIs
		state = 0;
		String yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.places%20where%20woeid%20in%20(select%20place.woeid%20from%20flickr.places%20where%20lat%3D50.8160844%20and%20lon%3D-0.3504952)&format=json";
		WeatherCompare.n.addRequest(yql, this);
	}

	private void getWOEID(JSONObject j) throws JSONException {
		String woeid = j.getJSONObject("query").getJSONObject("results").getJSONObject("place").getString("woeid");
		String yql = "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20xml%20where%20url%3D'http%3A%2F%2Fweather.yahooapis.com%2Fforecastrss%3Fw%3D" + woeid + "%26u%3Dc'&format=json";
		state = 1;
		WeatherCompare.n.addRequest(yql, this);
	}
	
	private void parseWeather(JSONObject j) throws JSONException {
		JSONObject channel = j.getJSONObject("query").getJSONObject("results").getJSONObject("rss").getJSONObject("channel");
		JSONObject item = channel.getJSONObject("item");
		JSONArray forecast = item.getJSONArray("forecast");
		WeatherObj weather = new WeatherObj();
		JSONObject todayForecast = forecast.getJSONObject(0);
		JSONObject tomorrowForecast = forecast.getJSONObject(1);
		weather.today.high = Integer.parseInt(todayForecast.getString("high"));
		weather.today.low = Integer.parseInt(todayForecast.getString("low"));
		weather.today.code = convertCode(Integer.parseInt(todayForecast.getString("code")));
		weather.today.text = todayForecast.getString("text");
		weather.tomorrow.high = Integer.parseInt(tomorrowForecast.getString("high"));
		weather.tomorrow.low = Integer.parseInt(tomorrowForecast.getString("low"));
		weather.tomorrow.code = convertCode(Integer.parseInt(tomorrowForecast.getString("code")));
		weather.tomorrow.text = tomorrowForecast.getString("text");
		wc.weatherCB(weather, this);
	}
	
	private int convertCode(int code) {
		int newCode;
		switch (code) {
			case 26:
				newCode = Weather.CLOUD;
	            break;
	            
	        // foggy
	        case 20:
	        case 21:
	            newCode = Weather.FOG;
	            break;
	        // sunny intervals
	        case 40:
	        	newCode = Weather.SUNNY_INTERVALS;
	        // rainy
	        case 1:
	        case 3:
	        case 4:
	        case 9:
	        case 10:
	        case 11:
	        case 12:
	            newCode = Weather.RAIN;
	            break;
	        //  snowy
	        case 5:
	        case 6:
	        case 7:
	        case 8:
	        case 13:
	        case 14:
	        case 15:
	        case 16:
	        case 17:
	        case 18:
	            newCode = Weather.SNOW;
	            break;
	        // sunny
	        case 32:
	            newCode = Weather.SUN;
	            break;
	        default: newCode = Weather.CLOUD;
		}
		
		return newCode;
	}
	
	public void netCallback(String s) throws IOException {
		try {
			JSONObject j = new JSONObject(s);
			
			switch (state) {
				case 0: {
					getWOEID(j);
					break;
				}
				
				case 1: {
					parseWeather(j);
					break;
				}
			}
			j = null;
			System.gc();
		} catch (JSONException e) {
			wc.weatherErr(this);
		}
	}

	public void netException(Exception exc) {
		wc.weatherErr(this);
	}

	public Image logo() { return Assets.YAHOO; }

	public String name() { return "Yahoo"; }
}
